package chan.project.aop;

import chan.project.constant.LocationConstant;
import chan.project.model.dto.travelPlan.GeneratedRoute;
import chan.project.model.entity.TravelPlan;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import chan.project.model.entity.Location;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@Aspect
@Component
public class LocationServiceAspect {

    @Resource
    private RedisTemplate<String,Object> redisTemplate;

    //检查locationService的保存操作，进行地点的缓存操作
    @Around("execution(* chan.project.service.LocationService.*(..))")
    public Object aroundLocationService(ProceedingJoinPoint joinPoint) throws Throwable {
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        //获取返回值
        Object proceed = joinPoint.proceed();
        //在getOne查询到数据之后如果redis中没有就更新到redis中
        if("getOne".equals(methodName)){
            Location location = (Location) proceed;
            if(location != null){
                Location cacheLocation = (Location) redisTemplate.opsForValue().get(LocationConstant.LOCATION_PREFIX + location.getName());
                if(cacheLocation == null){
                    redisTemplate.opsForValue().set(LocationConstant.LOCATION_PREFIX+location.getName(),location,1,TimeUnit.DAYS);
                }
            }
        }
        return proceed;
    }

    /**
     * 监听生成旅行计划方法进行排行榜的缓存
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around("execution(* chan.project.service.TravelPlanService.generateTravelPlan(..)))")
    public Object aroundTravelPlanController(ProceedingJoinPoint joinPoint) throws Throwable {
        //获取返回值
        Object proceed = joinPoint.proceed();
        TravelPlan travelPlan = (TravelPlan) proceed;

        //根据返回值更新每日排行榜
        List<GeneratedRoute> generatedRoute = JSONUtil.toList(travelPlan.getGeneratedRoute(), GeneratedRoute.class);
        for (GeneratedRoute location : generatedRoute) {
            Double currentScore = redisTemplate.opsForZSet().score(LocationConstant.LOCATION_RANK, location.getLocationName());
            if (currentScore != null) {
                redisTemplate.opsForZSet().incrementScore(LocationConstant.LOCATION_RANK, location.getLocationName(), 1.0); // 增加1
            } else {
                redisTemplate.opsForZSet().add(LocationConstant.LOCATION_RANK, location.getLocationName(), 0.0); // 添加并设置分数为0
                // 设置过期时间（例如：60秒）
                redisTemplate.expire(LocationConstant.LOCATION_RANK, 1, TimeUnit.DAYS);
            }
        }
        return proceed;
    }
}